package mymyoux.io.mserveur.mcontactClasses
{
	import mymyoux.core.IObject;
	import mymyoux.events.MEventDispatcher;
	import mymyoux.io.mserveur.MRoom;
	import mymyoux.io.mserveur.events.MRoomEvent;
	import mymyoux.io.mserveur.mcontactClasses.events.MRoomContactsEvent;
	import mymyoux.io.mserveur.mcontactClasses.events.PeopleEvent;
	import mymyoux.utils.Hash;
	/**
     * People dispatche l'event people_data quand le client envoie une donnée.
     * @eventType mymyoux.io.mserveur.mcontactClasses.events.PeopleEvent
     */
    [Event(name="people_data", type="mymyoux.io.mserveur.mcontactClasses.events.PeopleEvent")]
    	/**
     * People dispatche l'event people_in quand le client se connecte dans un autre salon.
     * @eventType mymyoux.io.mserveur.mcontactClasses.events.PeopleEvent
     */
    [Event(name="people_in", type="mymyoux.io.mserveur.mcontactClasses.events.PeopleEvent")]
        	/**
     * People dispatche l'event people_in quand le client se déconnecte d'un salon.
     * @eventType mymyoux.io.mserveur.mcontactClasses.events.PeopleEvent
     */
    [Event(name="people_out", type="mymyoux.io.mserveur.mcontactClasses.events.PeopleEvent")]
    	/**
     * People dispatche l'event people_offline quand le client n'est plus dans aucun salon.
     * @eventType mymyoux.io.mserveur.mcontactClasses.events.PeopleEvent
     */
    [Event(name="people_offline", type="mymyoux.io.mserveur.mcontactClasses.events.PeopleEvent")]
    
	/**
	 * Représente un Client.
	 * <p><b>Ne Pas instancier directement People</b></p>
	 */
	public class People extends MEventDispatcher implements IObject
	{
		/**
		 * @private
		 */
		protected var _idx:uint;
		/**
		 * @private
		 */
		protected var _login:String;
		/**
		 * Liste des salons dans lequel est le client.
		 */
		 protected var _rooms:Hash;
		/**
		 * Initialise un client avec son idx.
		 * @param idx Idx du client.
		 * @param login Pseudonyme du client.
		 */
		public function People(idx:uint,login:String="")
		{
			_login=login;
			_idx=idx;
			_rooms=new Hash();
		}
		/**
		 * Idx du client.
		 */
		 public function get idx():uint
		 {
		 	return _idx;
		 }
		 public function set idx(value:uint):void
		 {
		 	_idx=value;
		 	
		 }
		 /**
		 * Pseudonyme du client.
		 */
		 public function get login():String
		 {
		 	return _login;
		 }
		 public function set login(value:String):void
		 {
		 	_login=value;
		 	
		 }
		 /**
		 * @inheritDoc
		 */
		public override function toString():String
		{
			return "[People idx=\""+idx+"\" login=\""+login+"\"]";
		}
		 /**
		 * @inheritDoc
		 */
		public override function  destroy():void
		{
			var keys:Array=_rooms.getKeys();
			var room:MRoom;
			for(var p:String in keys)
			{
				room=_rooms.get(keys[p]) as MRoom;
				onPeopleOut(new MRoomContactsEvent(MRoomContactsEvent.PEOPLE_OUT,room,this));
			}
			super.destroy();
		}
		/**
		 * @inheritDoc
		 */
		public override function  equals(objet:IObject):Boolean
		{
			if(objet as People!=null)
			{
				if((objet as People).idx==idx)
				{
					return true;
				}
			}
			return false;
		}
		/**
		 * Ajoute un salon où se trouve le client.
		 * @param room Le Salon.
		 */
		public function addRoom(room:MRoom):void
		{
			_rooms.put(room.name,room);
			dispatchEvent(new PeopleEvent(PeopleEvent.PEOPLE_IN,room,this,this));
			room.addEventListener(MRoomEvent.DATA,onData);
			room.addEventListener(MRoomEvent.DISCONNECT,onRoomDisconnect);
			room.addEventListener(MRoomContactsEvent.PEOPLE_OUT,onPeopleOut);
		}
		/**
		 * Appelée par MRoom lorsqu'une donnée arrive.
		 * @param event Evenement dispatché par MRoom.
		 */
		protected function onData(event:MRoomEvent):void
		{
			if(event.idx==idx)
			{
				this.dispatchEvent(new PeopleEvent(PeopleEvent.PEOPLE_DATA,event.room,event.value,this));
				event.room.dispatchEvent(new PeopleEvent(PeopleEvent.PEOPLE_DATA,event.room,event.value,this));
				event.room.contacts.dispatchEvent(new PeopleEvent(PeopleEvent.PEOPLE_DATA,event.room,event.value,this));
			}
			
		}
		/**
		 * Appelée par MRoom lorsque le salon se ferme.
		 * @param event Evenement dispatché par MRoom.
		 */
		protected function onRoomDisconnect(event:MRoomEvent):void
		{
			if(_rooms.containsKey(event.room.name))
			{
				_rooms.remove(event.room.name);
				event.room.removeEventListener(MRoomEvent.DATA,onData);
				event.room.removeEventListener(MRoomEvent.DISCONNECT,onRoomDisconnect);
				event.room.removeEventListener(MRoomContactsEvent.PEOPLE_OUT,onPeopleOut);
				dispatchEvent(new PeopleEvent(PeopleEvent.PEOPLE_OUT,event.room,this,this));
				if(_rooms.length==0)
				{
					this.dispatchEvent(new PeopleEvent(PeopleEvent.PEOPLE_OFFLINE,event.room,this,this));
				}
			}
		}
		/**
		 * Appelée par MRoom lorsqu'un client quitte un salon
		 * @param event Evenement dispatché par MRoom.
		 */
		protected function onPeopleOut(event:MRoomContactsEvent):void
		{
			if(event.people.equals(this))
			{
				if(_rooms.containsKey(event.room.name))
				{
					_rooms.remove(event.room.name);
					event.room.removeEventListener(MRoomEvent.DATA,onData);
					event.room.removeEventListener(MRoomEvent.DISCONNECT,onRoomDisconnect);
					event.room.removeEventListener(MRoomContactsEvent.PEOPLE_OUT,onPeopleOut);
					dispatchEvent(new PeopleEvent(PeopleEvent.PEOPLE_OUT,event.room,this,this));
					if(_rooms.length==0)
					{
						this.dispatchEvent(new PeopleEvent(PeopleEvent.PEOPLE_OFFLINE,event.room,this,this));
					}
				}
			}
		}
		/**
		 * Envoie une donneé à ce client.
		 * Si room est précisée la donne passe par ce salon, sinon elle passe par le premier salon du hash.
		 * En cas d'incohérence, envoi d'une donnée à travers un salon où le joueur ne se trouve pas, ou vers un joueur inexistant
		 * rien ne se produit.
		 * @param value Donnée à envoyer.
		 * @param room Salon à travers lequel doit se faire l'échange.
		 */
		public function send(value:*,room:MRoom=null):void
		{
			if(_rooms.length>0)
			{
				if(!_rooms.containsKey(room.name))
				{
					room=null;
				}
				var keys:Array=_rooms.getKeys();
				room=(_rooms.get(keys[0]) as MRoom)
				room.sendPeople(this,value);
			}
		}

	}
}